﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using TekaMUD.Engine.Framework;
using TekaMUD.Engine.ServerTasks;
using TekaMUD.Engine.Workers;
using TekaMUD.Engine.IO;
using TekaMUD.Engine;
using TekaMUD.Engine.Blocks;

namespace TekaMUD.Engine.Commands
{
	/// <summary>
	/// Basic commands handlers. All static methods.
	/// </summary>
	public class BasicCommands
	{
		public static void Ping(Command c)
		{
			Messenger.SendAgent(c.Player,  "Pong!\r\n");
		}

		/// <summary>
		/// Prints system stats.
		/// </summary>
		public static void SystemStats(Command c)
		{
			Process p = Process.GetCurrentProcess();

			using (ChannelOutputHolder coh = new ChannelOutputHolder(c.Channel))
			{

				Messenger.SendAgent(c.Player, "\r\n");
				Messenger.SendAgent(c.Player, "System Stats\r\n");
				Messenger.SendAgent(c.Player, "Started at\t" + p.StartTime.ToString() + "\r\n");
				Messenger.SendAgent(c.Player, "Running for\t" + DateTime.Now.Subtract(p.StartTime).ToString() + "\r\n");
				Messenger.SendAgent(c.Player, "\r\n");
				Messenger.SendAgent(c.Player, "Running Threads:\r\n");

				foreach (WorkerThread pt in Supervisor.RegisteredThreads)
					Messenger.SendAgent(c.Player, "\t[" + pt.Name + "]\t(" + pt.ActivationDate.ToString() + ")\r\n");

				Messenger.SendAgent(c.Player, "\r\n");
				Messenger.SendAgent(c.Player, "Memory Stats\r\n");
				Messenger.SendAgent(c.Player, "\tVM Size:      " + p.VirtualMemorySize64 / 1024 + " KBytes\r\n");
				Messenger.SendAgent(c.Player, "\tWork Set:     " + p.WorkingSet64 / 1024 + " KBytes\r\n");
				Messenger.SendAgent(c.Player, "\tPaged System: " + p.PagedSystemMemorySize64 / 1024 + " KBytes\r\n");
				Messenger.SendAgent(c.Player, "\tPaged Memory: " + p.PagedMemorySize64 / 1024 + " KBytes\r\n");

				int total, opened, closed, other;

				ChannelManager.GetChannelStatistics(out total, out opened, out closed, out other);

				Messenger.SendAgent(c.Player, "\r\n");
				Messenger.SendAgent(c.Player, "Channels stats\r\n");
				Messenger.SendAgent(c.Player, "\tOpened:  " + opened + "\r\n");
				Messenger.SendAgent(c.Player, "\tClosed:  " + closed + "\r\n");
				Messenger.SendAgent(c.Player, "\tOther:   " + other + "\r\n");
				Messenger.SendAgent(c.Player, "\tTotal:   " + total + "\r\n");

				Messenger.SendAgent(c.Player, "\r\n");

				Messenger.SendAgent(c.Player, "Entity manager stats\r\n");

				Dictionary<Type, List<object>> db = EntityManager.CloneContents();

				foreach (KeyValuePair<System.Type, List<object>> KP in db)
				{
					Messenger.SendAgent(c.Player,"\t" + KP.Key.Name + "\r\n");

					foreach (object lo in KP.Value)
						Messenger.SendAgent(c.Player,"\t\t" + lo.ToString() + "\r\n");

					Messenger.SendAgent(c.Player,"\r\n");
				}
			}
		}

		public static void Terminate(Command c)
		{
			Logger.LogInfo("Terminating server...");
			Control.Terminate();

			//Logger.LogInfo("Updating world...");
			//Storage.UpdateWorld();

			
			System.Environment.Exit(0);
			
		}

		public static void Commit(Command c)
		{
			ServerTasksQueue.EnqueueTask(new SaveWorldTask());
			Logger.LogInfo("Queued...");
		}

		public static void Close(Command c)
		{
			Messenger.SendAgent(c.Player, "Closing connection...\r\n");
			
			c.Player.Status = TekaMUD.Engine.Blocks.PlayerStatus.Offline;

			c.Channel.Close();
		}

		/// <summary>
		/// Performs a controled shutdown of the server.
		/// </summary>
		public static void Shutdown(Command c)
		{
			// Closes the current players

			// Stops some threads.

			// Saves world.

			// kills current thread
		}
	}
}
